package yawning.mew.bear;

import yawning.mew.ProcEffect.Trigger;
import yawning.mew.character.CharacterModel.AttackResult;
import yawning.mew.sim.SimulationAction;
import yawning.mew.sim.SimulationEventAction;

public class MangleAction extends SimulationEventAction {
	BearThreatSimulator mState;
	double mCooldownExpireTime = 0.0;

	MangleAction(BearThreatSimulator state) {
		super(state.mSimEngine);

		mState = state;
	}

	@Override
	public double perform() {
		int cost = mState.mModel.mangleCost;

		if (!mState.hasRage(cost) && !mState.mOoCEv.isUp() &&
				!mState.mBerserkAction.isUp() && !mState.mBerserkProcEv.isUp()) return SimulationAction.ACTION_FAIL;
		if (mCooldownExpireTime > mState.mSimEngine.getSimTime()) return SimulationAction.ACTION_FAIL;

		AttackResult result = mState.mModel.getFrontalYellowResult();

		if (result == AttackResult.MISS) {
			mNrMangleMiss++;

			if (mState.mIsLogging) mState.mLog.log("Mangle: MISS\n");
		} else if (result == AttackResult.DODGE) {
			mNrMangleDodge++;

			if (mState.mIsLogging) mState.mLog.log("Mangle: DODGE\n");
		} else if (result == AttackResult.PARRY) {
			mNrMangleParry++;

			if (mState.mIsLogging) mState.mLog.log("Mangle: PARRY\n");
		} else {
			double damage = mState.mModel.getWeaponDamage() * mState.mModel.mLevelDep.getMangleMult() + mState.mModel.mLevelDep.getMangleDmg();

			damage *= mState.mModel.multMangleGlyph;

			if (result == AttackResult.CRIT) {
				mNrMangleCrit++;
				damage *= mState.mModel.multCrit;
			} else {
				mNrMangleHit++;
			}

			damage *= mState.getDirectDamageMult();
			mMangleDamage += Math.round(damage);

			if (mState.mIsLogging) mState.mLog.log("Mangle: %s Damage: %d\n", result, Math.round(damage));

			mState.mInfectedWoundsEv.onTrigger();

			if (mState.mModel.mToon.tier_12_2pc) mState.mTier_12_2pcEv.run(damage);

			if (result == AttackResult.CRIT) {
				mState.mSavageDefenseEv.onTrigger((mState.mModel.mToon.tier_13_2pc && mState.mPulverizeAction.isUp()));
				mState.mLotPEv.onTrigger();
				mState.mSimEngine.triggerProc(mState.mActiveTarget, Trigger.YELLOWCRIT);
			} else {
				mState.mSimEngine.triggerProc(mState.mActiveTarget, Trigger.YELLOW);
			}

			schedule(mState.mModel.mangleDebuffDuration);
		}

		if (mState.mBerserkAction.isUp()) {
			mNrBerserkMangle++;
		} else {
			mCooldownExpireTime = mState.mSimEngine.getSimTime() + mState.mModel.mangleCDDuration;

			if (mState.mBerserkProcEv.isUp()) {
				mNrBerserkProcMangle++;
				mState.mBerserkProcEv.onConsume();
			} else {
				mState.onRageLoss(cost);
			}
		}

		if (result == AttackResult.CRIT) mState.onPrimalFuryTrigger();

		return 1.5;
	}

	@Override
	public void onExpire() {
		if (mState.mIsLogging) mState.mLog.log("Mangle Expiration\n");
	}

	public void onBerserk() {
		mCooldownExpireTime = 0.0;
	}

	long mMangleDamage = 0;
	int mNrMangleMiss = 0;
	int mNrMangleDodge = 0;
	int mNrMangleParry = 0;
	int mNrMangleCrit = 0;
	int mNrMangleHit = 0;

	int mNrBerserkMangle = 0;
	int mNrBerserkProcMangle = 0;
}
